package com.zhoug.tmap.location;

import android.content.Context;
import android.location.Address;
import android.location.Geocoder;

import androidx.annotation.NonNull;

import com.zhoug.logging.Logger;
import com.zhoug.tmap.Callback;
import com.zhoug.tmap.http.Optional;

import java.io.IOException;
import java.util.List;
import java.util.Locale;

import io.reactivex.Observable;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;

/**
 * android 原生 地理编码api
 * @Author: zhoug
 * @Date: 2025-01-07
 * @Description:
 */
public class GeocoderHelper implements IGeocoder {
    private static final String TAG = ">>>GeocoderHelper";
    private static final boolean DEBUG = false;

    private Context mContext;

    public GeocoderHelper(Context context) {
        this.mContext = context;
    }

    /**
     * 通过经纬度获取地址信息
     * 同步调用
     *
     * @param latitude
     * @param longitude
     * @return
     */
    public ZAddress geocoderReverse(double latitude, double longitude) {
        Geocoder geocoder = new Geocoder(mContext, Locale.SIMPLIFIED_CHINESE);
        List<Address> addresses;
        try {
            addresses = geocoder.getFromLocation(latitude, longitude, 1);
            if (addresses != null && !addresses.isEmpty()) {
                Address address = addresses.get(0);
                if (DEBUG) {
                    Logger.d(TAG, "getLocality:" + address.getLocality());
                    Logger.d(TAG, "getAddressLine:" + address.getAddressLine(0));
                    Logger.d(TAG, "getAdminArea:" + address.getAdminArea());
                    Logger.d(TAG, "getCountryCode:" + address.getCountryCode());
                    Logger.d(TAG, "getCountryName:" + address.getCountryName());
                    Logger.d(TAG, "getFeatureName:" + address.getFeatureName());
                    Logger.d(TAG, "getPhone:" + address.getPhone());
                    Logger.d(TAG, "getPostalCode:" + address.getPostalCode());
                    Logger.d(TAG, "getPremises:" + address.getPremises());
                    Logger.d(TAG, "getSubAdminArea:" + address.getSubAdminArea());
                    Logger.d(TAG, "getSubLocality:" + address.getSubLocality());
                    Logger.d(TAG, "getSubThoroughfare:" + address.getSubThoroughfare());
                    Logger.d(TAG, "getThoroughfare:" + address.getThoroughfare());
                }
                ZAddress zAddress = new ZAddress.Builder()
                        .latitude(latitude)
                        .longitude(longitude)
                        .country(address.getCountryName())
                        .countryCode(address.getCountryCode())
                        .city(address.getAdminArea())
                        .street(address.getThoroughfare())
                        .streetNumber(address.getSubThoroughfare())
                        .address(address.getAddressLine(0))
                        .build();
                return zAddress;
            }
        } catch (IOException e) {
            Logger.e(TAG, "getAddressFromLocationSync:" + e.getMessage());
        }
        return null;
    }

    /**
     * 通过经纬度获取地址信息
     *
     * @param latitude
     * @param longitude
     * @param callback
     * @return
     */
    @Override
    public Disposable geocoderReverse(double latitude, double longitude, @NonNull Callback<ZAddress> callback) {
        Disposable disposable = Observable
                .create((ObservableOnSubscribe<Optional<ZAddress>>) emitter -> {
                    ZAddress address = geocoderReverse(latitude, longitude);
                    emitter.onNext(Optional.create(address));
                    emitter.onComplete();
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(s -> {
                    callback.onSuccess(s.get());
                }, throwable -> {
                    callback.onFailure(throwable.getMessage());
                });

        return disposable;
    }

}
